package com.superman.thread;

import cn.hutool.core.date.DateUtil;
import com.superman.thread.func.TakeHavingReturnHaving;
import com.superman.thread.func.TakeHavingReturnNothing;
import com.superman.thread.func.TakeNothingReturnHaving;
import com.superman.thread.func.TakeNothingReturnNothing;
import lombok.Data;
import lombok.ToString;

import java.io.Serializable;
import java.util.Date;
import java.util.concurrent.*;

/**
 * 任务主体
 *
 * @Author: superman
 * @Date: 2024/5/22 14:40
 */
@Data
@ToString
public class Task implements Serializable {
    private static final long serialVersionUID = 1L;

    /**
     * 任务ID
     */
    private String taskId;
    /**
     * 任务名称
     */
    private String taskName;
    /**
     * 任务主体
     */
    private Callable<Task> callable;
    /**
     * 回调任务主体
     * 任务执行成功才会执行的回调
     */
    private Callable<Object> callback;
    /**
     * 自动执行任务功能的回调,一定会执行
     */
    private Runnable autoNext;
    /**
     * 任务主体异常信息
     */
    private Exception exception;
    /**
     * 回调任务异常信息
     */
    private Exception callbackException;
    /**
     * 任务参数
     */
    private Object taskParam;
    /**
     * 任务执行结果
     */
    private Object taskResult;
    /**
     * 任务状态
     */
    private TaskStatusEnum taskStatus = TaskStatusEnum.WAITING;
    /**
     * 任务开始执行时间
     */
    private Date taskStartTime;
    /**
     * 任务执行结束时间
     */
    private Date taskEndTime;
    /**
     * 回调任务执行开始时间
     */
    private Date callBackStartTime;
    /**
     * 回调任务执行结束时间
     */
    private Date callBackEndTime;
    /**
     * 取消任务时间
     */
    private Date cancelledTime;
    /**
     * 中断任务时间
     */
    private Date interruptTime;
    /**
     * 任务提交信息
     */
    private Submit submit;
    /**
     * 任务执行结果，调用get方法会阻塞
     */
    private Future<?> future;
    /**
     * 任务执行线程
     */
    private Thread thread;
    /**
     * 任务执行日志 --> 暂时先不搞，没有好的方案
     */
    private String taskLog;
    ///////////////////////////////////////////////////////////////////////////////////////////
    ///////////////////////////////// 任务配置信息 //////////////////////////////////////////////
    ///////////////////////////////////////////////////////////////////////////////////////////
    /**
     * 任务是否可重复执行
     */
    private boolean repeat = false;
    /**
     * 重复执行策略，默认废弃后续
     */
    private RepeatStrategyEnum repeatStrategy = RepeatStrategyEnum.WASTE_AFTER;
    /**
     * 任务默认超时时长24H
     */
    private long timeout = 24;
    /**
     * 任务默认超时时长24H
     */
    private TimeUnit unit = TimeUnit.HOURS;


    private Task() {
    }

    /**
     * 构造无参有返回值的任务
     */
    protected <R> Task(String taskId, String taskName, TakeNothingReturnHaving<R> task) {
        this.taskId = taskId;
        this.taskName = taskName;
        this.callable = () -> {
            String name = null;
            try {
                this.thread = Thread.currentThread();
                name = this.thread.getName();
                this.thread.setName("task-" + this.taskId);
                this.taskStartTime = new Date();
                this.taskStatus = TaskStatusEnum.EXECUTING;
                this.taskResult = task.call();
                this.taskStatus = TaskStatusEnum.EXECUTED_SUCCESS;
                this.taskEndTime = new Date();
                if (null != this.callback) {
                    try {
                        this.callback.call();
                    } catch (Exception e) {
                        this.callbackException = e;
                    }
                }
            } catch (CancellationException exception) {
                // 任务取消
                this.exception = exception;
                this.taskStatus = TaskStatusEnum.EXECUTED_CANCELLED;
                this.cancelledTime = new Date();
            } catch (TimeoutException exception) {
                // 任务执行超时
                this.exception = exception;
                this.taskStatus = TaskStatusEnum.EXECUTED_TIMEOUT;
                this.taskEndTime = new Date();
            } catch (InterruptedException exception) {
                // 任务内部中断
                this.exception = exception;
                this.taskStatus = TaskStatusEnum.EXECUTED_INTERRUPT;
                this.interruptTime = new Date();
            } catch (Exception exception) {
                // 其它异常
                this.exception = exception;
                this.taskStatus = TaskStatusEnum.EXECUTED_FAIL;
                this.taskEndTime = new Date();
            } finally {
                if (null != thread && null != name) {
                    thread.setName(name);
                }
                if (null != this.autoNext) {
                    this.autoNext.run();
                }
            }
            return this;
        };
    }

    /**
     * 构造无参无返回值的任务
     */
    protected Task(String taskId, String taskName, TakeNothingReturnNothing task) {
        this.taskId = taskId;
        this.taskName = taskName;
        this.callable = () -> {
            String name = null;
            try {
                this.thread = Thread.currentThread();
                name = this.thread.getName();
                this.thread.setName("task-" + this.taskId);
                this.taskStartTime = new Date();
                this.taskStatus = TaskStatusEnum.EXECUTING;
                task.call();
                this.taskStatus = TaskStatusEnum.EXECUTED_SUCCESS;
                this.taskEndTime = new Date();
                if (null != this.callback) {
                    try {
                        this.callback.call();
                    } catch (Exception e) {
                        this.callbackException = e;
                    }
                }
            } catch (CancellationException exception) {
                // 任务取消
                this.exception = exception;
                this.taskStatus = TaskStatusEnum.EXECUTED_CANCELLED;
                this.cancelledTime = new Date();
            } catch (TimeoutException exception) {
                // 任务执行超时
                this.exception = exception;
                this.taskStatus = TaskStatusEnum.EXECUTED_TIMEOUT;
                this.taskEndTime = new Date();
            } catch (InterruptedException exception) {
                // 任务内部中断
                this.exception = exception;
                this.taskStatus = TaskStatusEnum.EXECUTED_INTERRUPT;
                this.interruptTime = new Date();
            } catch (Exception exception) {
                // 其它异常
                this.exception = exception;
                this.taskStatus = TaskStatusEnum.EXECUTED_FAIL;
                this.taskEndTime = new Date();
            } finally {
                if (null != this.thread && null != name) {
                    this.thread.setName(name);
                }
                if (null != this.autoNext) {
                    this.autoNext.run();
                }
            }
            return this;
        };
    }

    /**
     * 构造有参有返回值的任务
     */
    protected <R> Task(String taskId, String taskName, TakeHavingReturnHaving<R, Object> task, R param) {
        this.taskId = taskId;
        this.taskName = taskName;
        this.callable = () -> {
            String name = null;
            try {
                this.thread = Thread.currentThread();
                name = this.thread.getName();
                this.thread.setName("task-" + this.taskId);
                this.taskStartTime = new Date();
                this.taskParam = param;
                this.taskStatus = TaskStatusEnum.EXECUTING;
                this.taskResult = task.call(param);
                this.taskStatus = TaskStatusEnum.EXECUTED_SUCCESS;
                this.taskEndTime = new Date();
                if (null != this.callback) {
                    try {
                        this.callback.call();
                    } catch (Exception e) {
                        this.callbackException = e;
                    }
                }
            } catch (CancellationException exception) {
                // 任务取消
                this.exception = exception;
                this.taskStatus = TaskStatusEnum.EXECUTED_CANCELLED;
                this.cancelledTime = new Date();
            } catch (TimeoutException exception) {
                // 任务执行超时
                this.exception = exception;
                this.taskStatus = TaskStatusEnum.EXECUTED_TIMEOUT;
                this.taskEndTime = new Date();
            } catch (InterruptedException exception) {
                // 任务内部中断
                this.exception = exception;
                this.taskStatus = TaskStatusEnum.EXECUTED_INTERRUPT;
                this.interruptTime = new Date();
            } catch (Exception exception) {
                // 其它异常
                this.exception = exception;
                this.taskStatus = TaskStatusEnum.EXECUTED_FAIL;
                this.taskEndTime = new Date();
            } finally {
                if (null != this.thread && null != name) {
                    this.thread.setName(name);
                }
                if (null != this.autoNext) {
                    this.autoNext.run();
                }
            }
            return this;
        };
    }

    /**
     * 构造有参无返回值的任务
     */
    protected <R> Task(String taskId, String taskName, TakeHavingReturnNothing<R> task, R param) {
        this.taskId = taskId;
        this.taskName = taskName;
        this.callable = () -> {
            String name = null;
            try {
                this.thread = Thread.currentThread();
                name = this.thread.getName();
                this.thread.setName("task-" + this.taskId);
                this.taskStartTime = new Date();
                this.taskParam = param;
                this.taskStatus = TaskStatusEnum.EXECUTING;
                task.call(param);
                this.taskStatus = TaskStatusEnum.EXECUTED_SUCCESS;
                this.taskEndTime = new Date();
                if (null != this.callback) {
                    try {
                        this.callback.call();
                    } catch (Exception e) {
                        this.callbackException = e;
                    }
                }
            } catch (CancellationException exception) {
                // 任务取消
                this.exception = exception;
                this.taskStatus = TaskStatusEnum.EXECUTED_CANCELLED;
                this.cancelledTime = new Date();
            } catch (TimeoutException exception) {
                // 任务执行超时
                this.exception = exception;
                this.taskStatus = TaskStatusEnum.EXECUTED_TIMEOUT;
                this.taskEndTime = new Date();
            } catch (InterruptedException exception) {
                // 任务内部中断
                this.exception = exception;
                this.taskStatus = TaskStatusEnum.EXECUTED_INTERRUPT;
                this.interruptTime = new Date();
            } catch (Exception exception) {
                // 其它异常
                this.exception = exception;
                this.taskStatus = TaskStatusEnum.EXECUTED_FAIL;
                this.taskEndTime = new Date();
            } finally {
                if (null != this.thread && null != name) {
                    this.thread.setName(name);
                }
                if (null != this.autoNext) {
                    this.autoNext.run();
                }
            }
            return this;
        };
    }

    // TODO 后续添加回调函数的设置方法

    /**
     * 检查是否允许执行
     * 1、任务在删除状态，不允许执行
     * 2、不允许重复执行 + 任务待执行 = true, 其它状态都不允许执行
     * 3、允许重复执行 + 任务待执行 = true
     * 4、允许重复执行 + 执行完毕 = true
     * 5、允许重复执行 + 正在执行 + 串行 ==> 等待上一次执行完后再执行，true
     * 6、允许重复执行 + 正在执行 + 废弃后续 = false
     * 6、允许重复执行 + 正在执行 + 覆盖之前 ==> 先结束在执行的任务，再触发执行
     */
    private boolean checkRepeat(Long timeout, TimeUnit unit) {
        // 任务删除，不允许执行
        if (TaskStatusEnum.DELETED.equals(this.taskStatus)) {
            return false;
        }
        if (this.repeat) {
            if (TaskStatusEnum.EXECUTING.equals(this.taskStatus)) {
                // 根据阻塞策略判断
                if (RepeatStrategyEnum.SERIAL.equals(this.repeatStrategy)) {
                    // 串行，等待上一次执行完后再执行
                    return waitingEnd(timeout, unit);
                } else if (RepeatStrategyEnum.WASTE_AFTER.equals(this.repeatStrategy)) {
                    return false;
                } else if (RepeatStrategyEnum.OVERRIDE_BEFORE.equals(this.repeatStrategy)) {
                    return stop();
                }
            } else {
                return true;
            }
        } else {
            return TaskStatusEnum.WAITING.equals(this.taskStatus);
        }
        return false;
    }

    /**
     * 检查是否允许立即执行
     * 1、任务在删除状态，不允许执行
     * 2、不是正在执行状态 ==> true
     * 3、是正在执行状态 ==> 先结束在执行的任务，再触发执行
     */
    private boolean checkRepeatNow(Long timeout, TimeUnit unit) {
        // 任务删除，不允许执行
        if (TaskStatusEnum.DELETED.equals(this.taskStatus)) {
            return false;
        }
        return !TaskStatusEnum.EXECUTING.equals(this.taskStatus) || stop();
    }

    /**
     * 同步执行任务，会阻塞
     * 使用默认超时时间 24H
     *
     * @param pool 线程池
     */
    public Task syncTask(ExecutorService pool) {
        return syncTask(pool, this.timeout, this.unit);
    }

    /**
     * 同步执行任务并设置超时时间，会阻塞
     *
     * @param pool 线程池
     */
    public Task syncTask(ExecutorService pool, long timeout, TimeUnit unit) {
        // 检查是否允许执行
        if (checkRepeat(timeout, unit)) {
            // 异步执行任务，不会阻塞
            asyncTask(pool);
            // 等待任务执行完
            waitingEnd(timeout, unit);
        }
        return this;
    }

    /**
     * 异步执行任务，不会阻塞
     *
     * @param pool 线程池
     */
    public Future<?> asyncTask(ExecutorService pool) {
        // 检查是否允许执行
        if (checkRepeat(this.timeout, this.unit)) {
            executeInit();
            if (null != this.callable) {
                // 提交任务不会阻塞
                this.future = pool.submit(this.callable);
            } else {
                this.exception = new TaskException("未定义任务主体！");
                this.future = null;
            }
        }
        return this.future;
    }

    /**
     * 立即触发 同步执行任务，会阻塞
     * 使用默认超时时间 24H
     *
     * @param pool 线程池
     */
    public Task syncTaskNow(ExecutorService pool) {
        return syncTaskNow(pool, this.timeout, this.unit);
    }

    /**
     * 立即触发 同步执行任务并设置超时时间，会阻塞
     *
     * @param pool 线程池
     */
    public Task syncTaskNow(ExecutorService pool, long timeout, TimeUnit unit) {
        // 检查是否允许立即执行
        if (checkRepeatNow(timeout, unit)) {
            // 异步执行任务，不会阻塞
            asyncTaskNow(pool);
            // 等待任务执行完
            waitingEnd(timeout, unit);
        }
        return this;
    }

    /**
     * 立即触发 异步执行任务，不会阻塞
     *
     * @param pool 线程池
     */
    public Future<?> asyncTaskNow(ExecutorService pool) {
        // 检查是否允许立即执行
        if (checkRepeatNow(this.timeout, this.unit)) {
            executeInit();
            if (null != this.callable) {
                // 提交任务不会阻塞
                this.future = pool.submit(this.callable);
            } else {
                this.exception = new TaskException("未定义任务主体！");
                this.future = null;
            }
        }
        return this.future;
    }

    /**
     * 执行任务前，初始化相关的运行中参数
     */
    private void executeInit() {
        this.exception = null;
        this.callbackException = null;
        this.taskParam = null;
        this.taskResult = null;
        this.taskStatus = TaskStatusEnum.WAITING;
        this.taskStartTime = null;
        this.taskEndTime = null;
        this.callBackStartTime = null;
        this.callBackEndTime = null;
        this.cancelledTime = null;
        this.interruptTime = null;
        this.future = null;
        this.thread = null;
    }

    /**
     * 获取任务执行结果，如果任务还没完成则会阻塞等待直到任务执行完成。
     * 如果任务被取消则会抛出CancellationException异常，
     * 如果阻塞等待过程中超时则会抛出TimeoutException异常，
     * 如果阻塞等待过程中被中断则会抛出InterruptedException异常，
     *
     * @return true-任务已执行结束
     */
    public boolean waitingEnd() {
        return waitingEnd(this.timeout, this.unit);
    }

    /**
     * 获取任务执行结果，如果任务还没完成则会阻塞等待直到任务执行完成。
     * 如果任务被取消则会抛出CancellationException异常，
     * 如果阻塞等待过程中超时则会抛出TimeoutException异常，
     * 如果阻塞等待过程中被中断则会抛出InterruptedException异常，
     * 如果任务执行过程发生异常则会抛出ExecutionException异常。
     *
     * @param timeout 设置等待时间
     * @param unit    设置等待时间
     * @return true-任务已执行结束
     */
    public boolean waitingEnd(Long timeout, TimeUnit unit) {
        // boolean isDone();  如果任务完成，返回 true，完成可能是由于正常终止，异常或取消——在所有这些情况下，此方法将返回{@code true}。
        if (null == this.future || this.future.isDone()) return true;
        if ((null == timeout || unit == null)) {
            // 未设置超时时间 ==>  可能导致线程执行时间过长, 使用默认超时时长
            timeout = this.timeout;
            unit = this.unit;
        }
        try {
            // 等待任务执行完成，并捕获异常
            this.future.get(timeout, unit);
        } catch (CancellationException exception) {
            // 任务取消
            this.exception = exception;
            this.taskStatus = TaskStatusEnum.EXECUTED_CANCELLED;
            this.cancelledTime = new Date();
        } catch (TimeoutException exception) {
            // 任务执行超时
            this.exception = exception;
            this.taskStatus = TaskStatusEnum.EXECUTED_TIMEOUT;
            this.taskEndTime = new Date();
        } catch (InterruptedException exception) {
            // 任务内部中断
            this.exception = exception;
            this.taskStatus = TaskStatusEnum.EXECUTED_INTERRUPT;
            this.interruptTime = new Date();
        } catch (Exception exception) {
            // 其它异常
            this.exception = exception;
            this.taskStatus = TaskStatusEnum.EXECUTED_FAIL;
            this.taskEndTime = new Date();
        }
        return true;
    }

    /**
     * 删除当前任务
     * 如果任务正在执行，先销毁任务
     */
    public void delTask() {
        delTask(null);
    }

    /**
     * 删除当前任务
     * 如果任务正在执行，先销毁任务
     *
     * @param deleteReason 任务删除原因
     */
    public void delTask(String deleteReason) {
        if (TaskStatusEnum.EXECUTING.equals(this.taskStatus)) {
            this.stop();
        }
        this.taskStatus = TaskStatusEnum.DELETED;
        if (null != this.submit) {
            this.submit.setDeleteTime(new Date());
            this.submit.setDeleteReason(deleteReason);
        }
    }

    /**
     * 计算任务执行时长
     */
    public String cntExecuteTime() {
        if (null != this.taskStartTime) {
            if (TaskStatusEnum.EXECUTING.equals(this.taskStatus)) {
                return DateUtil.secondToTime(Math.toIntExact(DateUtil.betweenMs(this.taskStartTime, new Date()) / 1000));
            }
            if (TaskStatusEnum.EXECUTED_SUCCESS.equals(this.taskStatus)) {
                return DateUtil.secondToTime(Math.toIntExact(DateUtil.betweenMs(this.taskStartTime, this.taskEndTime) / 1000));
            }
            if (TaskStatusEnum.EXECUTED_CANCELLED.equals(this.taskStatus)) {
                return DateUtil.secondToTime(Math.toIntExact(DateUtil.betweenMs(this.taskStartTime, this.cancelledTime) / 1000));
            }
            if (TaskStatusEnum.EXECUTED_TIMEOUT.equals(this.taskStatus)) {
                return DateUtil.secondToTime(Math.toIntExact(DateUtil.betweenMs(this.taskStartTime, this.taskEndTime) / 1000));
            }
            if (TaskStatusEnum.EXECUTED_INTERRUPT.equals(this.taskStatus)) {
                return DateUtil.secondToTime(Math.toIntExact(DateUtil.betweenMs(this.taskStartTime, this.interruptTime) / 1000));
            }
            if (TaskStatusEnum.EXECUTED_FAIL.equals(this.taskStatus)) {
                return DateUtil.secondToTime(Math.toIntExact(DateUtil.betweenMs(this.taskStartTime, this.taskEndTime) / 1000));
            }
        }
        return "00:00:00";
    }

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////
    ///////////////////////////////////////////// 与线程执行有关的API /////////////////////////////////////////////
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////

    /**
     * 取消异步任务的执行
     * 1、立即放开 get(); 的阻塞，
     * 2、任务实际仍在运行，如果mayInterruptIfRunning参数为true，会设置中断标志
     *
     * @param mayInterruptIfRunning 如果任务线程正在执行是否设置中断标志
     * @return 1、如果异步任务已经完成或者已经被取消，或者由于某些原因不能取消，则会返回false；
     * 2、如果任务还没有被执行，则会返回true并且异步任务不会被执行;
     * 3、如果任务已经开始执行了但是还没有执行完成：若mayInterruptIfRunning为true，则会给执行任务的线程设置中断标志并返回true，
     * 若mayInterruptIfRunning为false，则会返回true且不会给任务执行线程设置中断标志。
     */
    public boolean cancel(boolean mayInterruptIfRunning) {
        if (null != this.future) {
            return this.future.cancel(mayInterruptIfRunning);
        }
        return true;
    }

    /**
     * 判断任务是否被取消：如果任务在结束(正常执行结束或者执行异常结束)前被取消则返回true，否则返回false。
     */
    public boolean isCancelled() {
        if (null != this.future) {
            return this.future.isCancelled();
        }
        return false;
    }

    /**
     * 判断任务是否已经完成，如果完成则返回true，否则返回false。需要注意的是：任务执行过程中发生异常、任务被取消也属于任务已完成，也会返回true。
     */
    public boolean isDone() {
        if (null != this.future) {
            return this.future.isDone();
        }
        return true;
    }

//    public void sleep() {} // 线程睡眠，强迫一线程睡N毫秒，sleep不会释放当前锁，导致线程进入TIMED_WAITING状态
//    public void interrupt() {} // 线程中断，调用一个线程的interrupt() 方法中断一个线程，并不是强行关闭这个线程，仅仅是改变了内部维护的中断标识位，是线程固有的一个标识位。可以调用在run内部根据thread.isInterrupted() 安全终止线程
//    public void wait() {} // 线程等待，调用该方法，线程进入WAITING状态，只有等待另外的线程通知或被中断才会返回，调用wait()后，会释放对象锁，因为wait方法一般用在同步方法或者同步代码块中
//    public void yield() {} // 线程让步，yeild会使当前线程让出cpu执行时间片，与其他线程一起重新竞争cpu时间片，一般情况下，优先级高的先得到
//    public void join() {} // 等待其他线程终止，当前线程调用join()，则线程转为阻塞状态，eg：A线程中插入了B.join()，则B先执行，执行完，A线程继续执行；常见的是主线程生成并启动了子线程，需要用到子线程返回结果的场景
//    public void notify() {} // 线程唤醒，Object类中的notify唤醒在此对象监视器上等待的单个线程；notifyAll唤醒在此对象监视器上等待的所有线程
//    public void notifyAll() {} // 线程唤醒，Object类中的notify唤醒在此对象监视器上等待的单个线程；notifyAll唤醒在此对象监视器上等待的所有线程

    /**
     * 给正在执行的任务线程打上中断标志
     */
    public void interrupt() {
        if (null != this.thread && isInterrupted()) {
            this.thread.interrupt();
        }
    }

    /**
     * 查看任务线程是否打上中断标志
     * 该方法不会清除中断标志
     * Thread.interrupted() 静态方法调用，返回当前线程(不是任务线程)是否打上中断标志，并且会清除中断标志
     */
    public boolean isInterrupted() {
        if (null != this.thread) {
            return this.thread.isInterrupted();
        }
        return false;
    }


    /**
     * 判断任务线程是否处于活动状态。
     * <p>
     * 线程生命周期(5种)与线程状态(6种)：
     * 1、每个线程要经历新生(new)、就绪(runnable)、运行(running)、阻塞(blocked)、死亡(dead)五种状态，线程从新生到死亡的状态变化过程称为线程的生命周期
     * NEW：新生状态，当一个线程的实例被创建即使用new关键字和Thread类或其子类创建一个线程对象后，此时该线程处于新生(new)状态，处于新生状态的线程有自己的内存空间，但该线程并没有运行，此时线程还不是活着的（not_alive）
     * RUNNABLE：就绪状态，通过调用线程实例的start()方法来启动线程使线程进入就绪状态(runnable)；处于就绪状态的线程已经具备了运行条件，但还没有被分配到CPU即不一定会被立即执行，此时处于线程就绪队列，等待系统为其分配CPU，等待状态并不是执行状态；此时线程是活着的（alive）
     * RUNNING：运行状态，一旦获取CPU(被JVM选中)，线程就进入运行(running)状态，线程的run()方法才开始被执行；在运行状态的线程执行自己的run()方法中的操作，直到调用其他的方法而终止、或者等待某种资源而阻塞、或者完成任务而死亡；如果在给定的时间片内没有执行结束，就会被系统给换下来回到线程的等待状态；此时线程是活着的（alive）
     * BLOCKED：阻塞状态，通过调用join()、sleep()、wait()或者资源被暂用使线程处于阻塞(blocked)状态；处于Blocking状态的线程仍然是活着的（alive）（阻塞状态其实是睡眠、资源阻塞、等待这三种状态的结合体。）
     * DEAD：死亡状态，当一个线程的run()方法运行完毕或被中断或被异常退出，该线程到达死亡(dead)状态。此时可能仍然存在一个该Thread的实例对象，当该Thread已经不可能在被作为一个可被独立执行的线程对待了，线程的独立的callstack已经被dissolved。一旦某一线程进入Dead状态，他就再也不能进入一个独立线程的生命周期了。对于一个处于Dead状态的线程调用start()方法，会出现一个运行期(runtimeException)的异常；处于Dead状态的线程不是活着的（not_alive）。
     * <p>
     * 2、线程的状态：New(新建)、Runnable（可运行)、Blocked（阻塞）、Waiting（等待）、Timed Waiting（计时等待)、Terminated（终止）
     * NEW：新生状态，当一个线程的实例被创建即使用new关键字和Thread类或其子类创建一个线程对象后，此时该线程处于新生(new)状态，处于新生状态的线程有自己的内存空间，但该线程并没有运行，此时线程还不是活着的（not_alive）
     * RUNNABLE：就绪状态，通过调用线程实例的start()方法来启动线程使线程进入就绪状态(runnable)；处于就绪状态的线程已经具备了运行条件，但还没有被分配到CPU即不一定会被立即执行，此时处于线程就绪队列，等待系统为其分配CPU，等待状态并不是执行状态；此时线程是活着的（alive）
     * BLOCKED：阻塞状态，通过调用join()、sleep()、wait()或者资源被暂用使线程处于阻塞(blocked)状态；处于Blocking状态的线程仍然是活着的（alive）（阻塞状态其实是睡眠、资源阻塞、等待这三种状态的结合体。）
     * WAITING：等待状态，处于这种状态的线程不会被CPU分配执行时间，他们要等待的显示被唤醒，否则会处于无限期的等待状态
     * TIMED_WAITING：超时等待，处于这种状态的线程不会被分配CPU执行时间，无需无限期的等待被其他线程显示的唤醒，比如用sleep方法传入一个要睡眠的时间，时间到了以后线程自己会醒
     * TERMINATED：终止状态，当线程的run（）方法完成时，或者主线程的run（）方法完成时，我们就认为他终止了。线程一旦终止了就不能复生
     *
     * @return <code>true</code>如果这个线程是活的;
     */
    public boolean isAlive() {
        if (null != this.thread) {
            return this.thread.isAlive();
        }
        return false;
    }

    /**
     * 设置任务线程的优先级
     * 所有线程的默认优先级为5
     * 线程优先级越高，获得 CPU 时间片的概率就越大,但线程优先级的高低与线程的执行顺序并没有必然联系
     *
     * @param newPriority 线程优先级
     */
    public void setPriority(int newPriority) {
        if (null != this.thread) {
            this.thread.setPriority(newPriority);
        }
    }

    /**
     * 查看任务线程的优先级
     */
    public int getPriority() {
        if (null != this.thread) {
            return this.thread.getPriority();
        }
        return 5;
    }

    /**
     * 获取任务线程的线程状态
     * 线程生命周期(5种)与线程状态(6种)：
     * 1、每个线程要经历新生(new)、就绪(runnable)、运行(running)、阻塞(blocked)、死亡(dead)五种状态，线程从新生到死亡的状态变化过程称为线程的生命周期
     * NEW：新生状态，当一个线程的实例被创建即使用new关键字和Thread类或其子类创建一个线程对象后，此时该线程处于新生(new)状态，处于新生状态的线程有自己的内存空间，但该线程并没有运行，此时线程还不是活着的（not_alive）
     * RUNNABLE：就绪状态，通过调用线程实例的start()方法来启动线程使线程进入就绪状态(runnable)；处于就绪状态的线程已经具备了运行条件，但还没有被分配到CPU即不一定会被立即执行，此时处于线程就绪队列，等待系统为其分配CPU，等待状态并不是执行状态；此时线程是活着的（alive）
     * RUNNING：运行状态，一旦获取CPU(被JVM选中)，线程就进入运行(running)状态，线程的run()方法才开始被执行；在运行状态的线程执行自己的run()方法中的操作，直到调用其他的方法而终止、或者等待某种资源而阻塞、或者完成任务而死亡；如果在给定的时间片内没有执行结束，就会被系统给换下来回到线程的等待状态；此时线程是活着的（alive）
     * BLOCKED：阻塞状态，通过调用join()、sleep()、wait()或者资源被暂用使线程处于阻塞(blocked)状态；处于Blocking状态的线程仍然是活着的（alive）（阻塞状态其实是睡眠、资源阻塞、等待这三种状态的结合体。）
     * DEAD：死亡状态，当一个线程的run()方法运行完毕或被中断或被异常退出，该线程到达死亡(dead)状态。此时可能仍然存在一个该Thread的实例对象，当该Thread已经不可能在被作为一个可被独立执行的线程对待了，线程的独立的callstack已经被dissolved。一旦某一线程进入Dead状态，他就再也不能进入一个独立线程的生命周期了。对于一个处于Dead状态的线程调用start()方法，会出现一个运行期(runtimeException)的异常；处于Dead状态的线程不是活着的（not_alive）。
     * <p>
     * 2、线程的状态：New(新建)、Runnable（可运行)、Blocked（阻塞）、Waiting（等待）、Timed Waiting（计时等待)、Terminated（终止）
     * NEW：新生状态，当一个线程的实例被创建即使用new关键字和Thread类或其子类创建一个线程对象后，此时该线程处于新生(new)状态，处于新生状态的线程有自己的内存空间，但该线程并没有运行，此时线程还不是活着的（not_alive）
     * RUNNABLE：就绪状态，通过调用线程实例的start()方法来启动线程使线程进入就绪状态(runnable)；处于就绪状态的线程已经具备了运行条件，但还没有被分配到CPU即不一定会被立即执行，此时处于线程就绪队列，等待系统为其分配CPU，等待状态并不是执行状态；此时线程是活着的（alive）
     * BLOCKED：阻塞状态，通过调用join()、sleep()、wait()或者资源被暂用使线程处于阻塞(blocked)状态；处于Blocking状态的线程仍然是活着的（alive）（阻塞状态其实是睡眠、资源阻塞、等待这三种状态的结合体。）
     * WAITING：等待状态，处于这种状态的线程不会被CPU分配执行时间，他们要等待的显示被唤醒，否则会处于无限期的等待状态
     * TIMED_WAITING：超时等待，处于这种状态的线程不会被分配CPU执行时间，无需无限期的等待被其他线程显示的唤醒，比如用sleep方法传入一个要睡眠的时间，时间到了以后线程自己会醒
     * TERMINATED：终止状态，当线程的run（）方法完成时，或者主线程的run（）方法完成时，我们就认为他终止了。线程一旦终止了就不能复生
     * <p>
     * 线程（Thread）：轻量级进程，是操作系统进行调度的最小单位。一个线程是一个任务（一个程序段）的一次执行过程。线程不占有内存空间，它包括在进程的内存空间中。在同一个进程内，多个线程共享进程的资源。一个进程至少有一个线程。
     */
    public Thread.State getState() {
        if (null != this.thread) {
            return this.thread.getState();
        }
        return null;
    }

    /**
     * 立即停止任务线程
     */
    public boolean stop() {
        if (null != this.thread) {
            // 直接关闭任务线程
            this.thread.stop();
        }
        return true;
    }
}
